package com.itsm.example.incident.flow.config;

import com.itsm.example.audit.pojo.event.AuditEvent;
import com.itsm.example.incident.flow.bo.IncidentEvent;
import com.itsm.example.incident.flow.bo.IncidentState;
import com.itsm.example.statemachine.bo.ItsmContext;
import com.itsm.example.statemachine.bo.ItsmEvent;
import com.itsm.example.statemachine.bo.ItsmState;
import com.itsm.example.statemachine.factory.StateMachineStrategy;
import com.itsm.statemachine.Action;
import com.itsm.statemachine.Condition;
import com.itsm.statemachine.StateMachine;
import com.itsm.statemachine.builder.StateMachineBuilder;
import com.itsm.statemachine.builder.StateMachineBuilderFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component

public class IncidentMachine  implements StateMachineStrategy {


    @Autowired
    private  Action<ItsmState, ItsmEvent, ItsmContext> newIncidentAction;
    @Autowired
    private  Condition<ItsmContext> incidentCondition;

    public static final String INCIDENT_STATEMACHINE_TYPE = "incidentStateMachine";

    @Bean
    public StateMachine<ItsmState, ItsmEvent, ItsmContext> incidentStateMachine() {
        StateMachineBuilder<ItsmState, ItsmEvent, ItsmContext> builder = StateMachineBuilderFactory.create();
        //新建工单
        builder.externalTransition().from(IncidentState.START).to(IncidentState.NEW)
                .on(IncidentEvent.SUBMIT)
                .when(incidentCondition)
                .perform(newIncidentAction);
//                .asyncPerform(asyncDoneAction)
        // 分派
        builder.externalTransition().from(IncidentState.NEW).to(IncidentState.FIRST_LINE_ASSIGN)
                .on(IncidentEvent.ASSIGN)
                .when(incidentCondition)
                .perform(newIncidentAction);
        // 解决
        builder.externalTransition().from(IncidentState.FIRST_LINE_ASSIGN).to(IncidentState.FIRST_LINE)
                .on(IncidentEvent.SOLVED)
                .when(incidentCondition)
                .perform(newIncidentAction);
        // 验证
        builder.externalTransition().from(IncidentState.FIRST_LINE).to(IncidentState.USER_VALIDATE)
                .on(IncidentEvent.VALIDATE)
                .when(incidentCondition)
                .perform(newIncidentAction);
        // 关闭
        builder.externalTransition().from(IncidentState.USER_VALIDATE).to(IncidentState.CLOSE)
                .on(IncidentEvent.CLOSE)
                .when(incidentCondition)
                .perform(newIncidentAction);
        // 设置线程池
        builder.setThreadPoolExecutor(new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors() * 2, // corePoolSize
                Runtime.getRuntime().availableProcessors() * 4, // maximumPoolSize
                60L, // keepAliveTime
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>() // workQueue
        ));
        return builder.build(getMachineType());
    }

    @Override
    public String getMachineType() {
        return INCIDENT_STATEMACHINE_TYPE;
    }
}
